/*
 *  Copyright (C) 2011 JiangHongTiao <jjurco.sk_gmail.com>
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package sk.lieskove.jianghongtiao.common.utils.xml;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;

/**
 * Date of create: May 15, 2011
 *
 * @author JiangHongTiao <jjurco.sk_gmail.com>
 * @version 2011.0515
 */
public class ProcessXML {
    
    private static DocumentBuilder getBuilder()throws SAXException, 
            ParserConfigurationException{
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        return factory.newDocumentBuilder();
    }
    
    public static Document openDocument(File file) 
            throws SAXException, ParserConfigurationException, IOException {
        return getBuilder().parse(file);
    }

    /**
     * open XML document and return his <code>Document</code> representation.
     * @param filName of XML document
     * @throws org.xml.sax.SAXException
     * @throws javax.xml.parsers.ParserConfigurationException
     * @throws java.io.IOException
     */
    public static Document openDocument(String fileName) 
            throws SAXException, ParserConfigurationException, IOException {
        return getBuilder().parse(fileName);
    }

    /**
     * write document to StreamResult
     * @return stream result with document
     * @throws java.io.IOException
     * @throws javax.xml.transform.TransformerConfigurationException
     * @throws javax.xml.transform.TransformerException
     */
    public static StringWriter serializeToXML(Document docToSerialize)
            throws IOException, TransformerConfigurationException, TransformerException {
        // Vytvorime instanci tovarni tridy
        TransformerFactory factory = TransformerFactory.newInstance();
        // Pomoci tovarni tridy ziskame instanci tzv. kopirovaciho transformeru
        Transformer transformer = factory.newTransformer();
        // Vstupem transformace bude dokument v pameti
        DOMSource source = new DOMSource((Node) docToSerialize);
        // Vystupem transformace bude vystupni soubor
        StringWriter out = new StringWriter();
        StreamResult result = new StreamResult(out);
        // Provedeme transformaci
        transformer.transform(source, result);

        return out;
    }

    /**
     * get node from current document by xPath query
     * @param xPathQuery query for node selection
     * @return node selected by query
     */
    public static Node getNodeByXPathQuery(String xPathQuery, Document doc) 
            throws XPathExpressionException {
        Node result = null;

        XPathFactory xPathFactory = XPathFactory.newInstance();
        XPath xPath = xPathFactory.newXPath();

        result = (Node) xPath.evaluate(xPathQuery, doc, XPathConstants.NODE);

        return result;
    }

    /**
     * 
     * @param query xPath query for selecting nodes
     * @param doc XML document
     * @return nodes match xPath query
     */
    public static NodeList getNodeListByXPathQuery(String query, Document doc) 
            throws XPathExpressionException {
        NodeList result = null;
        XPathFactory xPathFactory = XPathFactory.newInstance();
        XPath xPath = xPathFactory.newXPath();


        result = (NodeList) xPath.evaluate(query, doc, XPathConstants.NODESET);
        return result;
    }
}
